<?php
/**
 * 系统助手类
 * 
 * @author        shuguang <5565907@qq.com>
 * @copyright     Copyright (c) 2007-2013 bagesoft. All rights reserved.
 * @link          http://www.bagecms.com
 * @package       BageCMS.Tools
 * @license       http://www.bagecms.com/license
 * @version       v3.1.0
 */

class XUtils {

    /**
     * 友好显示var_dump
     */
    static public function dump( $var, $echo = true, $label = null, $strict = true ) {
        $label = ( $label === null ) ? '' : rtrim( $label ) . ' ';
        if ( ! $strict ) {
            if ( ini_get( 'html_errors' ) ) {
                $output = print_r( $var, true );
                $output = "<pre>" . $label . htmlspecialchars( $output, ENT_QUOTES ) . "</pre>";
            } else {
                $output = $label . print_r( $var, true );
            }
        } else {
            ob_start();
            var_dump( $var );
            $output = ob_get_clean();
            if ( ! extension_loaded( 'xdebug' ) ) {
                $output = preg_replace( "/\]\=\>\n(\s+)/m", "] => ", $output );
                $output = '<pre>' . $label . htmlspecialchars( $output, ENT_QUOTES ) . '</pre>';
            }
        }
        if ( $echo ) {
            echo $output;
            return null;
        } else
            return $output;
    }

	//打印并高亮函数
	static public function p($target,$bool=true){
	    static $i = 0;
	    if($i==0){
	        header('content-type:text/html;charset=utf-8');
	    }
	    echo '<pre>';
	    print_r($target);
	    $i++;
	    if($bool){
	       exit;
	    }else{
	        echo '<br />';
	    }
	}


    /**
     * 获取客户端IP地址
     */
    static public function getClientIP() {
        static $ip = NULL;
        if ( $ip !== NULL )
            return $ip;
        if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            $arr = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
            $pos = array_search( 'unknown', $arr );
            if ( false !== $pos )
                unset( $arr[$pos] );
            $ip = trim( $arr[0] );
        } elseif ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $ip = ( false !== ip2long( $ip ) ) ? $ip : '0.0.0.0';
        return $ip;
    }

    /**
     * 循环创建目录
     */
    static public function mkdir( $dir, $mode = 0777 ) {
        if ( is_dir( $dir ) || @mkdir( $dir, $mode ) )
            return true;
        if ( ! mk_dir( dirname( $dir ), $mode ) )
            return false;
        return @mkdir( $dir, $mode );
    }

    /**
     * 格式化单位
     */
    static public function byteFormat( $size, $dec = 2 ) {
        $a = array ( "B" , "KB" , "MB" , "GB" , "TB" , "PB" );
        $pos = 0;
        while ( $size >= 1024 ) {
            $size /= 1024;
            $pos ++;
        }
        return round( $size, $dec ) . " " . $a[$pos];
    }

    /**
     * 下拉框，单选按钮 自动选择
     *
     * @param $string 输入字符
     * @param $param  条件
     * @param $type   类型
     *            selected checked
     * @return string
     */
    static public function selected( $string, $param = 1, $type = 'select' ) {

        if ( is_array( $param ) ) {
            $true = in_array( $string, $param );
        }elseif ( $string == $param ) {
            $true = true;
        }
        if ( $true )
            $return = $type == 'select' ? 'selected="selected"' : 'checked="checked"';

        echo $return;
    }

    /**
     * 获得来源类型 post get
     *
     * @return unknown
     */
    static public function method() {
        return strtoupper( isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : 'GET' );
    }

    /**
     * 提示信息
     */
    static public function message( $action = 'success', $content = '', $redirect = 'javascript:history.back(-1);', $timeout = 4 ) {

        switch ( $action ) {
        case 'success':
            $titler = '操作完成';
            $class = 'message_success';
            $images = 'message_success.png';
            break;
        case 'error':
            $titler = '操作未完成';
            $class = 'message_error';
            $images = 'message_error.png';
            break;
        case 'errorBack':
            $titler = '操作未完成';
            $class = 'message_error';
            $images = 'message_error.png';
            break;
        case 'redirect':
            header( "Location:$redirect" );
            break;
        case 'script':
            if ( empty( $redirect ) ) {
                exit( '<script language="javascript">alert("' . $content . '");window.history.back(-1)</script>' );
            } else {
                exit( '<script language="javascript">alert("' . $content . '");window.location=" ' . $redirect . '   "</script>' );
            }
            break;
        }

        // 信息头部
        $header = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>操作提示</title>
<style type="text/css">
body{font:12px/1.7 "\5b8b\4f53",Tahoma;}
html,body,div,p,a,h3{margin:0;padding:0;}
.tips_wrap{ background:#F7FBFE;border:1px solid #DEEDF6;width:780px;padding:50px;margin:50px auto 0;}
.tips_inner{zoom:1;}
.tips_inner:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0;}
.tips_inner .tips_img{width:80px;float:left;}
.tips_info{float:left;line-height:35px;width:650px}
.tips_info h3{font-weight:bold;color:#1A90C1;font-size:16px;}
.tips_info p{font-size:14px;color:#999;}
.tips_info p.message_error{font-weight:bold;color:#F00;font-size:16px; line-height:22px}
.tips_info p.message_success{font-weight:bold;color:#1a90c1;font-size:16px; line-height:22px}
.tips_info p.return{font-size:12px}
.tips_info .time{color:#f00; font-size:14px; font-weight:bold}
.tips_info p a{color:#1A90C1;text-decoration:none;}
</style>
</head>

<body>';
        // 信息底部
        $footer = '</body></html>';

        $body = '<script type="text/javascript">
        function delayURL(url) {
        var delay = document.getElementById("time").innerHTML;
        //alert(delay);
        if(delay > 0){
        delay--;
        document.getElementById("time").innerHTML = delay;
    } else {
    window.location.href = url;
    }
    setTimeout("delayURL(\'" + url + "\')", 1000);
    }
    </script><div class="tips_wrap">
    <div class="tips_inner">
        <div class="tips_img">
            <img src="' . Yii::app()->baseUrl . '/static/images/' . $images . '"/>
        </div>
        <div class="tips_info">

            <p class="' . $class . '">' . $content . '</p>
            <p class="return">系统自动跳转在  <span class="time" id="time">' . $timeout . ' </span>  秒后，如果不想等待，<a href="' . $redirect . '">点击这里跳转</a></p>
        </div>
    </div>
</div><script type="text/javascript">
    delayURL("' . $redirect . '");
    </script>';

        exit( $header . $body . $footer );
    }

    /**
     * 查询字符生成
     */
    static public function buildCondition( array $getArray, array $keys = array() ) {
        if ( $getArray ) {
            foreach ( $getArray as $key => $value ) {
                if ( in_array( $key, $keys ) && $value ) {
                    $arr[$key] = CHtml::encode(strip_tags($value));
                }
            }
            return $arr;
        }
    }

    /**
     * base64_encode
     */
    static function b64encode( $string ) {
        $data = base64_encode( $string );
        $data = str_replace( array ( '+' , '/' , '=' ), array ( '-' , '_' , '' ), $data );
        return $data;
    }

    /**
     * base64_decode
     */
    static function b64decode( $string ) {
        $data = str_replace( array ( '-' , '_' ), array ( '+' , '/' ), $string );
        $mod4 = strlen( $data ) % 4;
        if ( $mod4 ) {
            $data .= substr( '====', $mod4 );
        }
        return base64_decode( $data );
    }

    /**
     * 验证邮箱
     */
    public static function email( $str ) {
        if ( empty( $str ) )
            return true;
        $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
        if ( strpos( $str, '@' ) !== false && strpos( $str, '.' ) !== false ) {
            if ( preg_match( $chars, $str ) ) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    
    /**
     * 验证手机号码
     */
    public static function mobile( $str ) {
        if ( empty( $str ) ) {
            return true;
        }

        return preg_match( '#^13[\d]{9}$|14^[0-9]\d{8}|^15[0-9]\d{8}$|^18[0-9]\d{8}$#', $str );
    }
    
    /**
     * 验证固定电话
     */
    public static function tel( $str ) {
        if ( empty( $str ) ) {
            return true;
        }
        return preg_match( '/^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/', trim( $str ) );

    }
    
    /**
     * 验证qq号码
     */
    public static function qq( $str ) {
        if ( empty( $str ) ) {
            return true;
        }

        return preg_match( '/^[1-9]\d{4,12}$/', trim( $str ) );
    }

    /**
     * 验证邮政编码
     */
    public static function zipCode( $str ) {
        if ( empty( $str ) ) {
            return true;
        }

        return preg_match( '/^[1-9]\d{5}$/', trim( $str ) );
    }
    
    /**
     * 验证ip
     */
    public static function ip( $str ) {
        if ( empty( $str ) )
            return true;

        if ( ! preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $str ) ) {
            return false;
        }

        $ip_array = explode( '.', $str );

        //真实的ip地址每个数字不能大于255（0-255）
        return ( $ip_array[0] <= 255 && $ip_array[1] <= 255 && $ip_array[2] <= 255 && $ip_array[3] <= 255 ) ? true : false;
    }

    /**
     * 验证身份证(中国)
     */
    public static function idCard( $str ) {
        $str = trim( $str );
        if ( empty( $str ) )
            return true;

        if ( preg_match( "/^([0-9]{15}|[0-9]{17}[0-9a-z])$/i", $str ) )
            return true;
        else
            return false;
    }

    /**
     * 验证网址
     */
    public static function url( $str ) {
        if ( empty( $str ) )
            return true;

        return preg_match( '#(http|https|ftp|ftps)://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?#i', $str ) ? true : false;
    }

    /**
     * 根据ip获取地理位置
     * @param $ip
     * return :ip,beginip,endip,country,area
     */
    public static function getlocation( $ip = '' ) {
        $ip = new XIp();
        $ipArr = $ip->getlocation( $ip );
        return $ipArr;
    }

    /**
     * 中文转换为拼音 
	 * echo XUtils::pinyin('开元壹号');
     */
    public static function pinyin( $str ) {
        $ip = new XPinyin();
        return $ip->output( $str );
    }

    /**
     * 拆分sql
     *
     * @param $sql
     */
    public static function splitsql( $sql ) {
         $sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=" . Yii::app()->db->charset, $sql);
        $sql = str_replace("\r", "\n", $sql);
        $ret = array ();
        $num = 0;
        $queriesarray = explode(";\n", trim($sql));
        unset($sql);
        foreach ($queriesarray as $query) {
            $ret[$num] = '';
            $queries = explode("\n", trim($query));
            $queries = array_filter($queries);
            foreach ($queries as $query) {
                $str1 = substr($query, 0, 1);
                if ($str1 != '#' && $str1 != '-')
                    $ret[$num] .= $query;
            }
            $num ++;
        }
        return ($ret);
    }

    /**
     * 字符截取
     *
     * @param $string
     * @param $length
     * @param $dot
     */
    public static function cutstr( $string, $length, $dot = '...', $charset = 'utf-8' ) {
        if ( strlen( $string ) <= $length )
            return $string;

        $pre = chr( 1 );
        $end = chr( 1 );
        $string = str_replace( array ( '&amp;' , '&quot;' , '&lt;' , '&gt;' ), array ( $pre . '&' . $end , $pre . '"' . $end , $pre . '<' . $end , $pre . '>' . $end ), $string );

        $strcut = '';
        if ( strtolower( $charset ) == 'utf-8' ) {

            $n = $tn = $noc = 0;
            while ( $n < strlen( $string ) ) {

                $t = ord( $string[$n] );
                if ( $t == 9 || $t == 10 || ( 32 <= $t && $t <= 126 ) ) {
                    $tn = 1;
                    $n ++;
                    $noc ++;
                } elseif ( 194 <= $t && $t <= 223 ) {
                    $tn = 2;
                    $n += 2;
                    $noc += 2;
                } elseif ( 224 <= $t && $t <= 239 ) {
                    $tn = 3;
                    $n += 3;
                    $noc += 2;
                } elseif ( 240 <= $t && $t <= 247 ) {
                    $tn = 4;
                    $n += 4;
                    $noc += 2;
                } elseif ( 248 <= $t && $t <= 251 ) {
                    $tn = 5;
                    $n += 5;
                    $noc += 2;
                } elseif ( $t == 252 || $t == 253 ) {
                    $tn = 6;
                    $n += 6;
                    $noc += 2;
                } else {
                    $n ++;
                }

                if ( $noc >= $length ) {
                    break;
                }

            }
            if ( $noc > $length ) {
                $n -= $tn;
            }

            $strcut = substr( $string, 0, $n );

        } else {
            for ( $i = 0; $i < $length; $i ++ ) {
                $strcut .= ord( $string[$i] ) > 127 ? $string[$i] . $string[++ $i] : $string[$i];
            }
        }

        $strcut = str_replace( array ( $pre . '&' . $end , $pre . '"' . $end , $pre . '<' . $end , $pre . '>' . $end ), array ( '&amp;' , '&quot;' , '&lt;' , '&gt;' ), $strcut );

        $pos = strrpos( $strcut, chr( 1 ) );
        if ( $pos !== false ) {
            $strcut = substr( $strcut, 0, $pos );
        }
        return $strcut . $dot;
    }

    /**
     * 描述格式化
     * @param  $subject
     */
    public static function clearCutstr ($subject, $length = 0, $dot = '...', $charset = 'utf-8')
    {
        if ($length) {
            return XUtils::cutstr(strip_tags(str_replace(array ("\r\n" ), '', $subject)), $length, $dot, $charset);
        } else {
            return strip_tags(str_replace(array ("\r\n" ), '', $subject));
        }
    }

    /**
     * 检测是否为英文或英文数字的组合
     *
     * @return unknown
     */
    public static function isEnglist( $param ) {
        if ( ! eregi( "^[A-Z0-9]{1,26}$", $param ) ) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 将自动判断网址是否加http://
     *
     * @param $http
     * @return  string
     */
    public static function convertHttp( $url ) {
        if ( $url == 'http://' || $url == '' )
            return '';

        if ( substr( $url, 0, 7 ) != 'http://' && substr( $url, 0, 8 ) != 'https://' )
            $str = 'http://' . $url;
        else
            $str = $url;
        return $str;

    }

    /*
        标题样式格式化
    */
    public static function titleStyle( $style ) {
        $text = '';
        if ( $style['bold'] == 'Y' ) {
            $text .='font-weight:bold;';
            $serialize['bold'] = 'Y';
        }

        if ( $style['underline'] == 'Y' ) {
            $text .='text-decoration:underline;';
            $serialize['underline'] = 'Y';
        }

        if ( !empty( $style['color'] ) ) {
            $text .='color:#'.$style['color'].';';
            $serialize['color'] = $style['color'];
        }

        return array( 'text' => $text, 'serialize'=>empty( $serialize )? '': serialize( $serialize ) );

    }

     // 自动转换字符集 支持数组转换
    static public function autoCharset ($string, $from = 'gbk', $to = 'utf-8')
    {
        $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
        $to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
        if (strtoupper($from) === strtoupper($to) || empty($string) || (is_scalar($string) && ! is_string($string))) {
            //如果编码相同或者非字符串标量则不转换
            return $string;
        }
        if (is_string($string)) {
            if (function_exists('mb_convert_encoding')) {
                return mb_convert_encoding($string, $to, $from);
            } elseif (function_exists('iconv')) {
                return iconv($from, $to, $string);
            } else {
                return $string;
            }
        } elseif (is_array($string)) {
            foreach ($string as $key => $val) {
                $_key = self::autoCharset($key, $from, $to);
                $string[$_key] = self::autoCharset($val, $from, $to);
                if ($key != $_key)
                    unset($string[$key]);
            }
            return $string;
        } else {
            return $string;
        }
    }

    /*
        标题样式恢复
    */
    public static function titleStyleRestore( $serialize, $scope = 'bold' ) {
        $unserialize = unserialize( $serialize );
        if ( $unserialize['bold'] =='Y' && $scope == 'bold' )
            return 'Y';
        if ( $unserialize['underline'] =='Y' && $scope == 'underline' )
            return 'Y';
        if ( $unserialize['color'] && $scope == 'color' )
            return $unserialize['color'];

    }

    /**
     * 列出文件夹列表
     *
     * @param $dirname
     * @return unknown
     */
    public static function getDir( $dirname ) {
        $files = array();
        if ( is_dir( $dirname ) ) {
            $fileHander = opendir( $dirname );
            while ( ( $file = readdir( $fileHander ) ) !== false ) {
                $filepath = $dirname . '/' . $file;
                if ( strcmp( $file, '.' ) == 0 || strcmp( $file, '..' ) == 0 || is_file( $filepath ) ) {
                    continue;
                }
                $files[] =  self::autoCharset( $file, 'GBK', 'UTF8' );
            }
            closedir( $fileHander );
        }
        else {
            $files = false;
        }
        return $files;
    }

    /**
     * 列出文件列表
     *
     * @param $dirname
     * @return unknown
     */
    public static function getFile( $dirname ) {
        $files = array();
        if ( is_dir( $dirname ) ) {
            $fileHander = opendir( $dirname );
            while ( ( $file = readdir( $fileHander ) ) !== false ) {
                $filepath = $dirname . '/' . $file;

                if ( strcmp( $file, '.' ) == 0 || strcmp( $file, '..' ) == 0 || is_dir( $filepath ) ) {
                    continue;
                }
                $files[] = self::autoCharset( $file, 'GBK', 'UTF8' );;
            }
            closedir( $fileHander );
        }
        else {
            $files = false;
        }
        return $files;
    }


    /**
     * [格式化图片列表数据]
     *
     * @return [type] [description]
     */
    public static function imageListSerialize( $data ) {

        foreach ( (array)$data['file'] as $key => $row ) {
            if ( $row ) {
                $var[$key]['fileId'] = $data['fileId'][$key];
                $var[$key]['file'] = $row;
            }

        }
        return array( 'data'=>$var, 'dataSerialize'=>empty( $var )? '': serialize( $var ) );

    }

    /**
     * 反引用一个引用字符串
     * @param  $string
     * @return string
     */
    static function stripslashes($string) {
        if(is_array($string)) {
            foreach($string as $key => $val) {
                $string[$key] = self::stripslashes($val);
            }
        } else {
            $string = stripslashes($string);
        }
        return $string;
    }
    
    /**
     * 引用字符串
     * @param  $string
     * @param  $force
     * @return string
     */
   static function addslashes($string, $force = 1) {
        if(is_array($string)) {
            foreach($string as $key => $val) {
                $string[$key] = self::addslashes($val, $force);
            }
        } else {
            $string = addslashes($string);
        }
        return $string;
    }

    /**
     * 格式化内容
     */
    static function formatHtml($content, $options = ''){
        $purifier = new CHtmlPurifier();
        if($options != false)
            $purifier->options = $options;
        return $purifier->purify($content);
    }


    /**
     * 将字符串转换为数组
     *
     * @param	string	$data	字符串
     * @return	array	返回数组格式，如果，data为空，则返回空数组
     */
    static function string2array($data) {
        if($data == '') return array();
        @eval("\$array = $data;");
        return @$array;
    }
    /**
     * 将数组转换为字符串
     *
     * @param	array	$data		数组
     * @param	bool	$isformdata	如果为0，则不使用new_stripslashes处理，可选参数，默认为1
     * @return	string	返回字符串，如果，data为空，则返回空
     */
    static function array2string($data, $isformdata = 1) {
        if($data == '') return '';
        if($isformdata) $data = self::new_stripslashes($data);
        return addslashes(var_export($data, TRUE));
    }


    /**
     * 下一个自增ID   Yii的感觉没这个好用  传入表名
     */
    static public function nextId($tables){
        preg_match('/^{{\S+}}$/', $tables) ? $table = $tables : $table = '{{'.$tables.'}}';
        $sql = "SHOW TABLE STATUS LIKE '$table'";
        $obj = Yii::app() -> db -> createCommand($sql);
        $row = $obj -> queryAll();
        return $row[0]['Auto_increment'];
    }

     /**
     * 返回经stripslashes处理过的字符串或数组
     * @param $string 需要处理的字符串或数组
     * @return mixed
     */
    static public function new_stripslashes($string) {
        if (!is_array($string)) return stripslashes($string);
        foreach($string as $key => $val) $string[$key] = self::new_stripslashes($val);
        return $string;
    }

    /**
     * 前台拼装url + openid
     */
    static public function wx_url($url,$openid) {
        if (empty($url)) {
            return false;
        }
        if (empty($openid)) {
            return false;
        }
        $arr = explode("#",$url);
        $str1 = $arr[0];
        $str = $str1.'&openid='.$openid.'#mp.weixin.qq.com';
        return $str;
    }



    /**
     * 获取Access Token
     *
     * @desc 公众号的全局唯一票据,公众号调用各接口时都需使用access_token
     * @param string $appid 凭证
     * @param string $appsecret 密钥
     * @return array
     */
    static public function get_access_token($appid, $appsecret) {
        static $token;
        if (!$appid || !$appsecret) {
            throw new Exception('非法调用函数：缺少appid或secret...');
        }
        if (!isset($token)) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
            $data = XUtils::http_request_get($url);
            $data = json_decode($data, true);
            if (isset($data['access_token'])) {
                $token = $data['access_token'];
            } else {
                return $data;
                //throw new Exception('获取access token失败...');
            }
        }
        return $token;
    }
    /**
    * 从微信服务器端获取用户信息
    *
    * @param $access_token
    * @param $openid
    * @return array $data
    */
    static public function get_weixin_user($access_token, $openid) {
        $wx_user_url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token={ACCESS_TOKEN}&openid={OPENID}&lang=zh_CN';
        if (empty($openid) || empty($access_token)) {
            return false;
        }
        $url = str_replace('{ACCESS_TOKEN}', $access_token, $wx_user_url);
        $url = str_replace('{OPENID}', $openid, $url);
        $json = http_request_get($url);
        $data = CJSON::decode($json, true);

        /**
         * {
        "subscribe": 1,
        "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
        "nickname": "Band",
        "sex": 1,
        "language": "zh_CN",
        "city": "广州",
        "province": "广东",
        "country": "中国",
        "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
        "subscribe_time": 1382694957
         * }
         */

        return $data;
    }
    static public function checkUser($wx_app_id,$wx_app_secret,$open_id,$user_token){
        $wx_user_db = new Wxuser();
        $wx_user_db->openid = trim($open_id);
        $wx_user_db->user_token = $user_token;
        $wx_user_db->share_time = time();
        $wx_user_db->save();
        $id = $wx_user_db->attributes['id'];
        $access_token = XUtils::get_access_token($wx_app_id,$wx_app_secret);
        if (!empty($access_token)) {
            //'real_name, phone'
            //微信用户信息
            $wx_user = XUtils::get_weixin_user($access_token, $open_id);
            $wx_user_info = Wxuser::model()->findByPk($id);
            $wx_user_info->nickname = $wx_user['nickname'] ? $wx_user['nickname'] : '';
            $wx_user_info->sex = $wx_user['sex'] ? $wx_user['sex'] : '';
            $wx_user_info->city = $wx_user['city'] ? $wx_user['city'] : '';
            $wx_user_info->province = $wx_user['province'] ? $wx_user['province'] : '';
            $wx_user_info->country = $wx_user['country'] ? $wx_user['country'] : '';
            $wx_user_info->language = $wx_user['language'] ? $wx_user['language'] : '';
            $wx_user_info->headimgurl = $wx_user['headimgurl'] ? $wx_user['headimgurl'] : '';
            $wx_user_info->subscribe_time = $wx_user['subscribe_time'] ? $wx_user['subscribe_time'] : '';
            $wx_user_info->save();
        }
    }
    /**
     * @author Asa_yang <88683231@qq.com>
     * @link http://www.hoohg.com/
     * @copyright Copyright &copy; 2011-2013 Hoohg Software LLC
     * @param string $length 随机hash的长度
     * @return hash 返回生成的哈希字符串
     *
     */
    //随机hash生成
    static public function randStr($length=10){
        $hash='';
        $chars= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';   //@#!~?:-
        $max=strlen($chars)-1;
        mt_srand((double)microtime()*1000000);
        for($i=0;$i<$length;$i++){
            $hash.=$chars[mt_rand(0,$max)];
        }
        return $hash;
    }


    static public function wxSharePic($url,$user_token){
        if(!$url) return false;
        $filename=date("dMYHis").self::randStr(5).'.jpg';
        $m = $user_token;
        $savefile = Yii::app()->basePath.'/www/uploads/share/'.$m.'/';
        $fileUrl = 'uploads/share/'.$m.'/';
        if(!is_dir($savefile)) mkdir($savefile, 0777,true);
        if(!is_readable($savefile)) chmod($savefile, 0777);
        $filenameurl = $fileUrl.$filename;//文件生成路径
        $filename = $savefile.$filename;//文件绝对地址
        $hander = curl_init();
        $fp = fopen($filename,'wb');
        curl_setopt($hander,CURLOPT_URL,$url);
        curl_setopt($hander,CURLOPT_FILE,$fp);
        curl_setopt($hander,CURLOPT_HEADER,0);
        curl_setopt($hander,CURLOPT_FOLLOWLOCATION,1);
        curl_setopt($hander,CURLOPT_TIMEOUT,60);
        curl_exec($hander);
        curl_close($hander);
        fclose($fp);
        return $filenameurl;
    }

    /**
     * 判断是刚刚 还是几分钟~~~~
     * @param $time
     * @return string
     */
    static public function tranTime($time)
    {
        $rtime = date("m-d H:i",$time);
        $htime = date("H:i",$time);

        $time = time() - $time;

        if ($time < 60)
        {
            $str = '刚刚';
        }
        elseif ($time < 60 * 60)
        {
            $min = floor($time/60);
            $str = $min.'分钟前';
        }
        elseif ($time < 60 * 60 * 24)
        {
            $h = floor($time/(60*60));
            $str = $h.'小时前 '.$htime;
        }
        elseif ($time < 60 * 60 * 24 * 3)
        {
            $d = floor($time/(60*60*24));
            if($d==1)
                $str = '昨天 '.$rtime;
            else
                $str = '前天 '.$rtime;
        }
        else
        {
            $str = $rtime;
        }
        return $str;
    }
    /**
     * 获取和设置配置参数 支持批量定义
     * @param string|array $name 配置变量
     * @param mixed $value 配置值
     * @param mixed $default 默认值
     * @return mixed
     */
    static public function C($name=null, $value=null,$default=null) {
        static $_config = array();
        // 无参数时获取所有
        if (empty($name)) {
            return $_config;
        }
        // 优先执行设置获取或赋值
        if (is_string($name)) {
            if (!strpos($name, '.')) {
                $name = strtoupper($name);
                if (is_null($value))
                    return isset($_config[$name]) ? $_config[$name] : $default;
                $_config[$name] = $value;
                return;
            }
            // 二维数组设置和获取支持
            $name = explode('.', $name);
            $name[0]   =  strtoupper($name[0]);
            if (is_null($value))
                return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default;
            $_config[$name[0]][$name[1]] = $value;
            return;
        }
        // 批量设置
        if (is_array($name)){
            $_config = array_merge($_config, array_change_key_case($name,CASE_UPPER));
            return;
        }
        return null; // 避免非法参数
    }






    /**
     *
     * function qrcode(){
     *     $filename='qrcode.png';
     *     $logo=SITE_PATH."\\Public\\Home\\images\\logo_80.png";
     *     qrcode('http://www.dellidc.com',$filename,false,$logo,8,'L',2,true);
     * }
     *
     * @param $data 二维码包含的文字内容
     * @param $filename 保存二维码输出的文件名称，*.png
     * @param bool $picPath 二维码输出的路径
     * @param bool $logo 二维码中包含的LOGO图片路径
     * @param string $size 二维码的大小
     * @param string $level 二维码编码纠错级别：L、M、Q、H
     * @param int $padding 二维码边框的间距
     * @param bool $saveandprint 是否保存到文件并在浏览器直接输出，true:同时保存和输出，false:只保存文件
     * return string
     */
    static public function qrcode($data,$filename,$picPath=false,$logo=false,$size='4',$level='L',$padding=2,$saveandprint=false){
        Yii::import('application.vendor.*');
        require_once('Tp/phpqrcode/phpqrcode.php');

        // 下面注释了把二维码图片保存到本地的代码,如果要保存图片,用$fileName替换第二个参数false
        if($picPath){
            $path = $picPath ? $picPath : Yii::app()->homeUrl."\\Uploads\\Picture\\QRcode"; //图片输出路径
            mkdir($path);
        }
        //在二维码上面添加LOGO
        if(empty($logo) || $logo=== false) { //不包含LOGO
            if ($filename==false) {
                QRcode::png($data, false, $level, $size, $padding, $saveandprint); //直接输出到浏览器，不含LOGO
            }else{
                $filename=$path.'/'.$filename; //合成路径
                QRcode::png($data, $filename, $level, $size, $padding, $saveandprint); //直接输出到浏览器，不含LOGO
            }
        }else { //包含LOGO
            if ($filename==false){
                //$filename=tempnam('','').'.png';//生成临时文件
                die('参数错误');
            }else {
                //生成二维码,保存到文件
                $filename = $path . '\\' . $filename; //合成路径
            }
            QRcode::png($data, $filename, $level, $size, $padding);
            $QR = imagecreatefromstring(file_get_contents($filename));
            $logo = imagecreatefromstring(file_get_contents($logo));
            $QR_width = imagesx($QR);
            $QR_height = imagesy($QR);
            $logo_width = imagesx($logo);
            $logo_height = imagesy($logo);
            $logo_qr_width = $QR_width / 5;
            $scale = $logo_width / $logo_qr_width;
            $logo_qr_height = $logo_height / $scale;
            $from_width = ($QR_width - $logo_qr_width) / 2;
            imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
            if ($filename === false) {
                Header("Content-type: image/png");
                imagepng($QR);
            } else {
                if ($saveandprint === true) {
                    imagepng($QR, $filename);
                    header("Content-type: image/png");//输出到浏览器
                    imagepng($QR);
                } else {
                    imagepng($QR, $filename);
                }
            }
        }
        return $filename;
    }

    static public function isAuth($app_id,$ap_secret){
            $code = Yii::app()->request->getParam('code');
            //通过code获得openid
            if (!$code){
                //触发微信返回code码
                $baseUrl = urlencode(Yii::app()->request->hostInfo.Yii::app()->request->getUrl());
                $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$app_id.'&redirect_uri='.$baseUrl.'&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect';
                Header("Location: $url");
                exit();
            } else {
                $access_token = self::getAccessToken($code,$app_id,$ap_secret);
                if($access_token['errcode']=='40029'){
                    //触发微信返回code码
                    $urls = Yii::app()->request->hostInfo.Yii::app()->request->getUrl();
                    $baseUrl = urlencode($urls);
                    $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$app_id.'&redirect_uri='.$baseUrl.'&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect';
                    Header("Location: $url");
                    exit();
                }
                return $userinfo = self::getUserInfo($access_token['access_token'],$access_token['openid']);
            }

    }
    static public function isBasicAuth($app_id,$ap_secret){
            $code = Yii::app()->request->getParam('code');
            //通过code获得openid
            if (!$code){
                //触发微信返回code码
                $baseUrl = urlencode(Yii::app()->request->hostInfo.Yii::app()->request->getUrl());
                $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$app_id.'&redirect_uri='.$baseUrl.'&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
                Header("Location: $url");
                exit();
            } else {
                $access_token = self::getAccessToken($code,$app_id,$ap_secret);
                if($access_token['errcode']=='40029'){

                        $urls = Yii::app()->request->hostInfo.Yii::app()->request->getUrl();
                        $baseUrl = urlencode($urls);

                    //触发微信返回code码
                    $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$app_id.'&redirect_uri='.$baseUrl.'&response_type=code&scope=snsapi_base&state=1#wechat_redirect';
                    Header("Location: $url");
                    exit();
                }
                return $openid = $access_token['openid'];
            }

    }
    static public function getAccessToken($code,$appid,$secret){
        $url = self::__CreateOauthUrlForOpenid($code,$appid,$secret);
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res,true);
        return $data;

    }
    static public function __CreateOauthUrlForOpenid($code,$appid,$secret)
    {
        $urlObj["appid"] = $appid;
        $urlObj["secret"] = $secret;
        $urlObj["code"] = $code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString = self::ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
    }

    /**
     *
     * 拼接签名字符串
     * @param array $urlObj
     *
     * @return 返回已经拼接好的字符串
     */
    static public function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v)
        {
            if($k != "sign"){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    static public function getUserInfo($access_token,$openid){
        $url = self::__CreateUserInfo($access_token,$openid);
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res,true);
        return $data;
    }

    static public function __CreateUserInfo($access_token,$openid){
        $urlObj["access_token"] = $access_token;
        $urlObj["openid"] = $openid;
        $urlObj["lang"] = "zh_CN";
        $bizString = self::ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/userinfo?".$bizString;
    }






    /**
     * 生成签名信息
     * @param  string $ut UserToken
     * @return string     [description]
     */
    static public function getSignPackage($app_id, $app_secret, $url,$con = '') {

        $jsapiTicket = self::getJsApiTicket($app_id, $app_secret,$con);

        $timestamp = time();
        $nonceStr = self::createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $ticket = $jsapiTicket['ticket'];

        $string = "jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

        $signature = sha1($string);

        $signPackage = array(
            "appId"     => $app_id,
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return stripslashes(json_encode($signPackage));
    }

    /**
     * 获得SDK Ticket
     * @param  string $ut UserToken
     * @return string     [description]
     */
    static public function getJsApiTicket($app_id, $app_secret,$id)
    {
        $mark = $app_id.$app_secret.$id;

        $products = Yii::app()->cache->get($mark);

        if ($products===false) {
            $access_token = XUtils::get_access_token($app_id, $app_secret);


            $ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=". $access_token ."&type=jsapi";
            $result = json_decode(XUtils::http_request_get($ticket_url), true);
            if($result){
                if($result['errcode']==0){
                    $data = array(
                        'ticket' => $result['ticket'],
                        'app_id' => $app_id
                    );
                }else{
                    $data = array( //达到上限
                        'ticket' => '',
                        'app_id' => $app_id
                    );
                }
            }else{
                $data = array(
                    'ticket' => '',
                    'app_id' => $app_id
                );
            }

            Yii::app()->cache->set($mark, $data,1800);
            return $data;
        } else {
            return $products;
        }
    }
    /**
     * 随机数
     * @param  integer $length [description]
     * @return [type]          [description]
     */
    static public function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    /**
     * GET方式请求
     */
    static public function http_request_get($url=null, $data=null) {
        return XUtils::http_request($url, $data);
    }

    /**
     * POST方式请求
     */
    static public function http_request_post($url=null, $data=null) {
        return XUtils::http_request($url, $data, '', 'post');
    }
    /**
     * Http请求
     */
    static public function http_request($url, $data, $refererUrl = '', $method = 'GET', $contentType = 'application/json', $timeout = 30, $proxy = false) {
        $ch = null;
        if('POST' === strtoupper($method)) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            //不建议绕过验证
            //@see http://stackoverflow.com/questions/6400300/php-curl-https-causing-exception-ssl-certificate-problem-verify-that-the-ca-cer
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
            if ($refererUrl) {
                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
            }
            if($contentType) {
                curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:'.$contentType));
            }
            if(is_string($data)){
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            }
        } else if('GET' === strtoupper($method)) {
            if (isset($data)) {
                if(is_string($data)) {
                    $real_url = $url. (strpos($url, '?') === false ? '?' : ''). $data;
                } else {
                    $real_url = $url. (strpos($url, '?') === false ? '?' : ''). http_build_query($data);
                }
            } else {
                $real_url = $url;
            }

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $real_url);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:'.$contentType));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            //不建议绕过验证
            //http://stackoverflow.com/questions/6400300/php-curl-https-causing-exception-ssl-certificate-problem-verify-that-the-ca-cer
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);	// no verify
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
            if ($refererUrl) {
                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
            }
        } else {
            //$args = func_get_args();
            throw new Exception('无效参数...');
            return false;
        }

        if($proxy) {
            curl_setopt($ch, CURLOPT_PROXY, $proxy);
        }
        $ret = curl_exec($ch);
        curl_close($ch);
        return $ret;
    }
}
/**
 * GET方式请求
 */
function http_request_get($url=null, $data=null) {
    return http_request($url, $data);
}

/**
 * POST方式请求
 */
function http_request_post($url=null, $data=null) {
    return http_request($url, $data, '', 'post');
}
/**
 * 获取Access Token
 *
 * @desc 公众号的全局唯一票据,公众号调用各接口时都需使用access_token
 * @param string $appid 凭证
 * @param string $appsecret 密钥
 * @return array
 */
function get_access_token($appid, $appsecret) {
    static $token;
    if (!$appid || !$appsecret) {
        throw new Exception('非法调用函数：缺少appid或secret...');
    }
    if (!isset($token)) {
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
        $data = http_request_get($url);
        $data = json_decode($data, true);
        if (isset($data['access_token'])) {
            $token = $data['access_token'];
        } else {
            return $data;
            //throw new Exception('获取access token失败...');
        }
    }
    return $token;
}

?>
